#!/usr/bin/env python

# send_file.py - A pygtk2 application to demonstrate bluetooth functions
#
# Version 0.1
#
# Authors: Erin Yueh <erinyueh@gmail.com>
#
# Copyright (c) 2008 Erin Yueh
#
# send_file.py is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at your
# option) any later version.
#
# browse_device.py is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.


import pygtk
pygtk.require('2.0')

import gtk, gobject
# Check for new pygtk: this is new class in PyGtk 2.4
if gtk.pygtk_version < (2,3,90):
   print "PyGtk 2.3.90 or later required for this example"
   raise SystemExit

from xml.dom.minidom import parseString
import lightblue

class FileSelectionExample:
    # Get the selected filename and print it to the console
    def file_ok_sel(self, w):
        print "%s" % self.filew.get_filename()
        dev = SelectDevice(self.bt,self.filew.get_filename())
        self.filew.destroy()
        
    def destroy(self, widget):
        self.filew.destroy()

    def __init__(self,bt):
        self.bt = bt
        # Create a new file selection widget
        self.filew = gtk.FileSelection("File selection")

        self.filew.connect("destroy", self.destroy)
        # Connect the ok_button to file_ok_sel method
        self.filew.ok_button.connect("clicked", self.file_ok_sel)

        # Connect the cancel_button to destroy the widget
        self.filew.cancel_button.connect("clicked",
                                         lambda w: self.filew.destroy())

        # Lets set the filename, as if this were a save dialog,
        # and we are giving a default filename
        self.filew.set_filename("penguin.png")

        self.filew.show()

class SelectDevice:
    
    # close the window and quit
    def delete_event(self, widget, event, data=None):
        print 'delete_event:', widget,event
        self.w.destroy()
        return False
        
    def col1_toggled_cb( self, treeview, path, column ):
        print 'toggle_cb'
        model = treeview.get_model()
        iter  = model.get_iter(path)
        selected_dev_name = model.get_value(iter,0)
        addr = self.dev_list[selected_dev_name]
        print selected_dev_name,addr
        self.prepare_to_send(addr)

    def __browsexml(self, doc):
        record = doc.documentElement
        for node in record.childNodes:
            if node.nodeType == node.ELEMENT_NODE and node.getAttribute('id') == '0x0004':
                val = node.getElementsByTagName('uint8')
                return int(val[0].getAttribute('value'), 16)

    def resolveService(self, addr, service='FTP' ): 

        service_handle = self.bt.bluetooth_adapter.getRemoteServiceHandles(addr,'FTP')
        if service_handle:
            xml = self.bt.bluetooth_adapter.getRemoteServiceRecordAsXML(addr,service_handle[0])
            doc = parseString(xml)
            return self.__browsexml(doc)
        else:
            return None

    def prepare_to_send(self,addr):
        print 'prepare to send',addr,self.sendfname
        channel = self.resolveService(addr)
        if channel:
            print 'sendfile', addr, channel,self.sendfname
            try:
                lightblue.obex.sendfile(addr,channel,self.sendfname)
            except Exception,e:
                print 'sendfile ERROR',e 
        else:
            print 'No FTP service'

    def __init__(self,bt,name):
        print 'SelectDevice: dev_list'
        self.sendfname = name
        self.bt = bt
        # create a liststore with 2 columns
        self.liststore = gtk.ListStore(str, str)
        
        # Create new windows
        self.w = gtk.Window(gtk.WINDOW_TOPLEVEL)
        win = self.w
        win.set_title("Select Device")
        win.set_size_request(220, 200)
        win.connect("delete_event", self.delete_event)
        
        win.vbox = gtk.VBox()
        win.add(win.vbox)
        win.sw = gtk.ScrolledWindow()
        win.sm = gtk.TreeModelSort(self.liststore)
        # Set sort column
        win.sm.set_sort_column_id(1, gtk.SORT_ASCENDING)

        win.tv = gtk.TreeView(win.sm)
        win.tv.connect("row-activated", self.col1_toggled_cb)
        win.vbox.pack_start(win.sw)

        win.sw.add(win.tv)
        win.tv.column = [None]*2
        win.tv.column[0] = gtk.TreeViewColumn('Name')
        win.tv.column[1] = gtk.TreeViewColumn('Device Type')
        win.tv.cell = [None]*2
        
        for i in range(2):
            win.tv.cell[i] = gtk.CellRendererText()
            win.tv.append_column(win.tv.column[i])
            win.tv.column[i].set_sort_column_id(i)
            win.tv.column[i].pack_start(win.tv.cell[i], True)
            win.tv.column[i].set_attributes(win.tv.cell[i], text=i)

        # display ListBondings
        list_bonding = self.bt.bluetooth_adapter.listBondings()
        print list_bonding
        self.dev_list = {}
        
        for addr in list_bonding:
            name = self.bt.bluetooth_adapter.getRemoteName(addr)
            dtype = self.bt.bluetooth_adapter.getRemoteMajorClass(addr)
            self.w.sm.get_model().append([name,dtype])
            self.dev_list[name] = addr

        win.show_all()